package com.lancoo.ccas52.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lancoo.ccas52.aspect.LogAnnotation;
import com.lancoo.ccas52.aspect.RateLimiter;
import com.lancoo.ccas52.config.LancooConfig;
import com.lancoo.ccas52.entity.*;
import com.lancoo.ccas52.pojo.common.PageInfo;
import com.lancoo.ccas52.pojo.dto.Building;
import com.lancoo.ccas52.pojo.vo.*;
import com.lancoo.ccas52.schedues.BackupDatabase;
import com.lancoo.ccas52.service.*;
import com.lancoo.ccas52.util.PagingUtil;
import com.lancoo.ccas52.util.ResponseObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @ClassName CommonController
 * @Description TODO
 * @Author quin
 * @Date 2022/12/21 15:58
 */
@Api(tags = "任务控制器")
@RestController
@RequestMapping("/api/v5.2.1/pc/common")
public class CommonController {

    @Resource
    private TaskInfoService taskInfoService;

    @Resource
    private TaskProcessService taskProcessService;

    @Resource
    private CollegeDealTimeService collegeDealTimeService;

    @Resource
    private UserSettingService userSettingService;
    @Resource
    private RoomService roomService;
    @Resource
    private RoomTypeService roomTypeService;
    @Resource
    private LancooConfig lancooConfig;
    @Resource
    private BackupDatabase backupDatabase;

    @ApiOperation("test")
    @GetMapping("/test")
    public void test(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                     @ApiParam(value = "学期", required = true) @RequestParam   @Validated @NotBlank String term) {
        System.out.println(schoolId);
        System.out.println(term);
    }

    @ApiOperation("开启新学期计划")
    @PostMapping("/addTask")
    @LogAnnotation(operationType = "1", entityName = "taskInput", fieldName = "taskName", operationContent = "开启新学期排课计划")
    public ResponseObject<TaskInfo> createTask(@ApiParam(value = "任务", required = true) @RequestBody TaskInput taskInput) {
        return ResponseObject.ofSuccess(taskInfoService.addTask(taskInput));
    }

    @ApiOperation("获取全部计划")
    @GetMapping("/getTaskList")
    public ResponseObject<PageInfo<TaskInfo>> getTaskList(@ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                                          @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                          @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        LambdaQueryWrapper<TaskInfo> queryWrapper = new LambdaQueryWrapper<TaskInfo>().eq(TaskInfo::getFlag, 0)
                .eq(TaskInfo::getSchoolId, schoolId);
        List<TaskInfo> taskList = taskInfoService.list(queryWrapper);
        List<TaskInfo> sortTask = taskList.stream().sorted(Comparator.comparing(TaskInfo::getTerm).reversed()).collect(Collectors.toList());
        PageInfo<TaskInfo> pageTask = PagingUtil.getPages(currentPage, pageSize, sortTask);
        return ResponseObject.ofSuccess(pageTask);
    }

    @ApiOperation("判断是否存在学期计划")
    @GetMapping("/isExistTask")
    @Deprecated
    public ResponseObject<Boolean> isExistTask(@ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                               @ApiParam(value = "学期", required = true) @RequestParam String term) {
        boolean exists = taskInfoService.lambdaQuery().eq(TaskInfo::getSchoolId, schoolId).eq(TaskInfo::getTerm, term).exists();
        return ResponseObject.ofSuccess(exists);
    }

    @ApiOperation("根据id删除计划")
    @DeleteMapping("/removeTaskByIds")
    @LogAnnotation(operationType = "4", fieldName = "taskIds", operationContent = "删除计划")
    public ResponseObject<Object> removeTaskByIds(@ApiParam(value = "任务ids", required = true) @RequestBody List<Integer> taskIds) {
        taskInfoService.removeTaskByIds(taskIds);
        return ResponseObject.ofSuccess("删除成功");
    }

    @ApiOperation("开启任务时获取年级信息")
    @GetMapping(value = "/getGradeOnTask")
    public ResponseObject<List<GradeDto>> getGrade(@ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                                   @ApiParam(value = "学期id", required = true) @RequestParam String term) {
        return ResponseObject.ofSuccess(taskInfoService.getGrade(schoolId, term));
    }

    @ApiOperation("获取周次信息")
    @GetMapping(value = "/week/{taskId}")
    public ResponseObject<WeekDateVo> countWeek(@ApiParam(value = "任务Id", required = true) @PathVariable Integer taskId) {
        return ResponseObject.ofSuccess(taskInfoService.countWeek(taskId));
    }

    @ApiOperation("任务各阶段状态")
    @GetMapping(value = "taskProgress/{taskId}")
    public ResponseObject<List<TaskProcess>> getTaskProgress(@ApiParam(value = "任务Id", required = true) @PathVariable Integer taskId) {
        return ResponseObject.ofSuccess(taskProcessService.getProcessList(taskId));
    }

    @ApiOperation("修改任务阶段状态")
    @GetMapping(value = "taskProgress/update")
    @LogAnnotation(operationType = "2", operationContent = "修改任务阶段状态")
    public ResponseObject<Boolean> updateTaskProgress(@ApiParam(value = "任务流程id", required = true) @RequestParam Integer id,
                                                      @ApiParam(value = "0未完成  1已完成", required = true) @RequestParam Integer finish) {
        return ResponseObject.ofSuccess(taskProcessService.updateProcess(id, finish));
    }


    @ApiOperation("申请时间设置")
    @PostMapping("/addOrUpdateDealTime")
    @LogAnnotation(operationType = "2", entityName = "dealTimeInput", fieldName = "type", operationContent = "申请时间设置")
    public ResponseObject<CollegeDealTime> addOrUpdateDealTime(@ApiParam(value = "处理时间实体类", required = true) @RequestBody DealTimeInput dealTimeInput) {
        return ResponseObject.ofSuccess(collegeDealTimeService.addOrUpdateDealTime(dealTimeInput));
    }

    @ApiOperation("获取开课单位处理时间")
    @GetMapping(value = "getDealTime")
    public ResponseObject<CollegeDealTime> getDealTime(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                       @ApiParam(value = "1:开课计划 2:预选课程->开课单位处理时段 3:教学任务", required = true) @RequestParam Integer type) {
        return ResponseObject.ofSuccess(collegeDealTimeService.getDealTime(taskId, type));
    }

    @ApiOperation("获取校区")
    @GetMapping("/campus/get")
    public ResponseObject<List<Campus>> getCampusList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return ResponseObject.ofSuccess(roomService.getCampusList(taskId));
    }

    @ApiOperation("获取学院")
    @GetMapping(value = "/getCollege")
    public ResponseObject<List<CollegeDto>> getTeacherPlan(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                           @ApiParam(value = "1教学计划-专业 2课程 3环节 4学生", required = true) @RequestParam Integer module) {
        return ResponseObject.ofSuccess(taskInfoService.getCollegeByTaskId(taskId, module));
    }

    @ApiOperation("获取年级")
    @GetMapping(value = "/getGrade")
    public ResponseObject<List<GradeDto>> getGrade(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                   @ApiParam(value = "1教学计划 2课程 3环节 4学生", required = true) @RequestParam Integer module) {
        return ResponseObject.ofSuccess(taskInfoService.getGradeByTaskId(taskId, module));
    }

    @ApiOperation("获取专业")
    @GetMapping(value = "/getMajor")
    public ResponseObject<List<MajorDto>> getMajor(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                   @ApiParam(value = "1教学计划 2课程 3环节 4学生", required = true) @RequestParam Integer module,
                                                   @ApiParam(value = "学院id", required = false) @RequestParam(required = false) String collegeId) {
        return ResponseObject.ofSuccess(taskInfoService.getMajorByTaskId(taskId, module, collegeId));
    }

    @ApiOperation("获取班级")
    @GetMapping(value = "/getClass")
    public ResponseObject<List<ClassDto>> getClass(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                   @ApiParam(value = "1教学计划 2课程 3环节 4学生", required = true) @RequestParam Integer module,
                                                   @ApiParam(value = "学院id", required = false) @RequestParam(required = false) String collegeId,
                                                   @ApiParam(value = "专业id", required = false) @RequestParam(required = false) String majorId,
                                                   @ApiParam(value = "年级id", required = false) @RequestParam(required = false) String gradeId) {
        return ResponseObject.ofSuccess(taskInfoService.getClassByTaskId(taskId, module, collegeId, majorId, gradeId));
    }

    @ApiOperation("获取用户配置")
    @GetMapping(value = "/getSidebar")
    public ResponseObject<UserSetting> getUserSetting(@ApiParam(value = "用户id", required = true) @RequestHeader String userId) {
        UserSetting userSetting = userSettingService.getUserSettingByUserId(userId);
        return ResponseObject.ofSuccess(userSetting);
    }

    @ApiOperation("设置用户侧边栏配置")
    @PostMapping(value = "/setSidebar")
    @LogAnnotation(operationType = "2", operationContent = "设置用户侧边栏配置")
    public ResponseObject<Boolean> addOrUpdateSetting(@ApiParam(value = "用户配置类", required = true) @RequestBody UserSetting userSetting) {
        return ResponseObject.ofSuccess(userSettingService.updateUserSetting(userSetting));
    }

    @ApiOperation("获取教室类型")
    @GetMapping(value = "/getRoomType")
    public ResponseObject<Object> getRoomType(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                              @ApiParam(value = "学期", required = true) @RequestParam String term,
                                              @ApiParam(value = "学校Id", required = false) @RequestParam(required = false) Integer type) {
        return ResponseObject.ofSuccess(roomService.getRoomType(schoolId, term, type));
    }

    @GetMapping("/getBuilding")
    @ApiOperation("获取楼宇")
    public ResponseObject<List<Building>> getBuilding(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                      @ApiParam(value = "学期", required = true) @RequestParam String term) {
        return ResponseObject.ofSuccess(roomService.getBuilding(schoolId, term));
    }

    @GetMapping("/getFloor")
    @ApiOperation("获取楼层")
    public ResponseObject<List<Integer>> getFloor(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                  @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                  @ApiParam(value = "楼宇id", required = false) @RequestParam(required = false) Integer buildingId) {
        return ResponseObject.ofSuccess(roomService.getFloor(schoolId, term, buildingId));
    }

    @GetMapping("/getYmlConfig")
    @ApiOperation("获取配置文件信息")
    public ResponseObject<LancooConfigVo> getYmlConfig() {
        LancooConfigVo lancooConfigVo = new LancooConfigVo()
                .setBaseAddr(lancooConfig.getBaseAddr())
                .setLockerId(lancooConfig.getLockerId())
                .setSysId(lancooConfig.getSysId())
                .setConnectSection(lancooConfig.getConnectSection())
                .setAppdataResource(lancooConfig.getAppdataResource());
        return ResponseObject.ofSuccess(lancooConfigVo);
    }

    @GetMapping("/roomType")
    @ApiOperation("获取所有教室类型")
    public ResponseObject<List<RoomType>> getRoomType(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                      @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                      @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                      @ApiParam(value = "学校Id", required = false) @RequestParam(required = false) Integer type) {
        return ResponseObject.ofSuccess(roomTypeService.getRoomType(taskId,schoolId,term,type));
    }

    @PostMapping("/addRoomType")
    @ApiOperation("新增教室类型")
    public ResponseObject<RoomType> addRoomType(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                @ApiParam(value = "类型", required = true) @Validated @RequestBody RoomType roomType) {

        return ResponseObject.ofSuccess(roomTypeService.addRoomType(taskId,schoolId,term,roomType));
    }

    @PostMapping("/updateRoomType")
    @ApiOperation("修改教室类型")
    public ResponseObject<Object> updateRoomType(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                 @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                 @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                @ApiParam(value = "类型", required = true) @Validated @RequestBody RoomType roomType) {
        roomTypeService.updateRoomType(taskId,schoolId,term,roomType);
        return ResponseObject.ofSuccess();
    }

    @PostMapping("/removeRoomType")
    @ApiOperation("删除教室类型")
    public ResponseObject<Object> removeRoomType(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                 @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                 @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                 @ApiParam(value = "类型id", required = true) @RequestParam Integer id) {

        roomTypeService.removeRoomType(taskId,schoolId,term,id);
        return ResponseObject.ofSuccess();
    }
}
